package com.wjq.boot.service.impl;

import com.aventrix.jnanoid.jnanoid.NanoIdUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.wjq.boot.entity.UploadFile;
import com.wjq.boot.mapper.UploadFileMapper;
import com.wjq.boot.service.UploadFileService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.errors.*;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;

/**
 * <p>
 * 文件表 服务实现类
 * </p>
 *
 * @author wangjiaquan
 * @since 2024-08-08
 */
@Service
public class UploadFileServiceImpl extends ServiceImpl<UploadFileMapper, UploadFile> implements UploadFileService {

    @Resource
    private UploadFileMapper uploadFileMapper;

    @Value("${minio.client.url}")
    private String url;

    @Value("${minio.client.username}")
    private String username;

    @Value("${minio.client.password}")
    private String password;

    @Override
    public UploadFile get(String md5, Long size, String contentType) {
        QueryWrapper<UploadFile> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("md5",md5).eq("size",size).eq("content_type",contentType);
        return uploadFileMapper.selectOne(queryWrapper);
    }

    @Override
    public String upload(String bucket, MultipartFile file) throws IOException, ServerException, InsufficientDataException, ErrorResponseException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {
        // 获取文件的类型
        String contentType = file.getContentType();
        // 获取文件的MD5
        String md5 = DigestUtils.md5Hex(file.getInputStream());
        // 获取文件的大小
        long size = file.getSize();
        UploadFile uploadFile = get(md5, size, contentType);
        if(uploadFile != null){
            return uploadFile.getPath();
        }
        MinioClient client = MinioClient.builder()
                .credentials(username,password) // 服务器的用户名和密码
                .endpoint(url)  // 服务器的网址
                .build();
        // 文件的重命名
        String fileName = NanoIdUtils.randomNanoId() + "." + FilenameUtils.getExtension(file.getOriginalFilename());
        // 调用Minio客户端上传
        PutObjectArgs args = PutObjectArgs.builder()
                .bucket(bucket)
                .contentType(contentType)
                .stream(file.getInputStream(), size, 0)
                .object(fileName)
                .build();
        // 上传文件
        client.putObject(args);
        String path = "/" + bucket + "/" + fileName;
        this.save(new UploadFile(md5,size,contentType,path));
        return path;
    }
}
